package org.one.stone.soup.grfxML;

import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.util.Vector;

import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;
import org.one.stone.soup.mjdb.data.field.LockException;
import org.one.stone.soup.mjdb.data.field.NullField;
import org.one.stone.soup.xml.XmlElement;
  /*
 * Copyright 2000-2001 Wet-Wired.com Ltd.,
 * Portsmouth England
 * All rights reserved.
 */

/**
	*
	* @author Nik Cross
*/
public class DataMouse extends NullField implements ITag {
	public static String DEFAULT_ID = "_Mouse";

	DataState buttonDoubleClicked = new DataState(false);
	DataState buttonPressed = new DataState(false);
	DataState buttonReleased = new DataState(false);
	private DataState buttonDown = new DataState(false);

	DataState button1DoubleClicked = new DataState(false);
	DataState button1Pressed = new DataState(false);
	DataState button1Released = new DataState(false);
	private DataState button1Down = new DataState(false);

	DataState button2DoubleClicked = new DataState(false);
	DataState button2Pressed = new DataState(false);
	DataState button2Released = new DataState(false);
	private DataState button2Down = new DataState(false);

	DataPoint lastPosition = new DataPoint();
	DataPoint lastPositionView = new DataPoint();
	DataPoint position = new DataPoint();
	DataPoint positionView = new DataPoint();
	DataPoint pressPosition = new DataPoint();
	DataPoint pressPositionView = new DataPoint();

	DataPoint velocity = new DataPoint();
	DataPoint velocityView = new DataPoint();

	DataState sticky = new DataState(false);

	int _cursorMode = Cursor.DEFAULT_CURSOR;

	private ITag _over;
	private ITag _held;
	private ITag _lastHeld;

	private Vector events;
	private Vector cutEvents;
public DataMouse() {
	try{
		setId(DEFAULT_ID,this);
	}
	catch(LockException le){} //Dummy catch
}
public void buildFromgrfxML(XmlElement xml)
{

	String name = xml.getAttributeValueByName(Token.ID);
	if(name!=null)
	{
		try{
			setId(name,this);
		}
		catch(LockException le){} //Dummy catch
	}

	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.BUTTON_PRESSED))
		{
			buttonPressed = new DataState(false);
	  		buttonPressed.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_DOUBLE_CLICKED))
		{
			buttonDoubleClicked = new DataState(false);
	  		buttonDoubleClicked.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_RELEASED))
		{
			buttonReleased = new DataState(false);
			buttonReleased.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_DOWN))
		{
			buttonDown = new DataState(false);
			buttonDown.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.LAST_POSITION))
		{
			lastPosition = new DataPoint(TagModifier.POINT_TYPE_POINT);
			lastPosition.buildFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.POSITION))
		{
			position = new DataPoint(TagModifier.POINT_TYPE_POINT);
			position.buildFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.PRESS_POSITION))
		{
			pressPosition = new DataPoint(TagModifier.POINT_TYPE_POINT);
			pressPosition.buildFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.VELOCITY))
		{
			velocity = new DataPoint(TagModifier.POINT_TYPE_VECTOR);
	  		velocity.buildFromgrfxML(element,TagModifier.POINT_TYPE_VECTOR);
		}
		else if(eleName.equals(Token.STICKY))
		{
			sticky = new DataState(false);
	  		sticky.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_PRESSED))
		{
			button1Pressed = new DataState(false);
	  		button1Pressed.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_DOUBLE_CLICKED))
		{
			button1DoubleClicked = new DataState(false);
	  		button1DoubleClicked.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_RELEASED))
		{
			button1Released = new DataState(false);
			button1Released.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_DOWN))
		{
			button1Down = new DataState(false);
			button1Down.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_PRESSED))
		{
			button2Pressed = new DataState(false);
	  		button2Pressed.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_DOUBLE_CLICKED))
		{
			button2DoubleClicked = new DataState(false);
	  		button2DoubleClicked.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_RELEASED))
		{
			button2Released = new DataState(false);
			button2Released.buildFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_DOWN))
		{
			button2Down = new DataState(false);
			button2Down.buildFromgrfxML(element);
		}
		else if( !NameHelper.isSystemName(element.getName()) )
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.MOUSE,""+element.getStartLineNo()} );
		}
	}
}
public void copyFromgrfxML(XmlElement xml)
{
	XmlElement element;

	for(int loop=0;loop<xml.getElementCount();loop++)
	{
		element = xml.getElementByIndex(loop);
		if(element == null)
			continue;

		String eleName = element.getName();

		if(eleName.equals(Token.BUTTON_PRESSED))
		{
	  		buttonPressed.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_DOUBLE_CLICKED))
		{
	  		buttonDoubleClicked.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_RELEASED))
		{
			buttonReleased.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON_DOWN))
		{
			buttonDown.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.LAST_POSITION))
		{
			lastPosition.copyFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.POSITION))
		{
			position.copyFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.PRESS_POSITION))
		{
			pressPosition.copyFromgrfxML(element,TagModifier.POINT_TYPE_POINT);
		}
		else if(eleName.equals(Token.VELOCITY))
		{
	  		velocity.copyFromgrfxML(element,TagModifier.POINT_TYPE_VECTOR);
		}
		else if(eleName.equals(Token.STICKY))
		{
	  		sticky.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_PRESSED))
		{
	  		button1Pressed.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_DOUBLE_CLICKED))
		{
	  		button1DoubleClicked.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_RELEASED))
		{
			button1Released.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON1_DOWN))
		{
			button1Down.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_PRESSED))
		{
	  		button2Pressed.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_DOUBLE_CLICKED))
		{
	  		button2DoubleClicked.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_RELEASED))
		{
			button2Released.copyFromgrfxML(element);
		}
		else if(eleName.equals(Token.BUTTON2_DOWN))
		{
			button2Down.copyFromgrfxML(element);
		}
		else
		{
			GrfxMLException.warning( GrfxMLException.WARNING_UNRECOGNISED_TAG_CODE ,new Object[]{eleName,Token.MOUSE,""+element.getStartLineNo()} );
		}
	}
}
public DataState getButton1DoubleClicked() {
	return button1DoubleClicked;
}
public DataState getButton1Down() {
	return button1Down;
}
public DataState getButton1Pressed() {
	return button1Pressed;
}
public DataState getButton1Released() {
	return button1Released;
}
public DataState getButton2DoubleClicked() {
	return button2DoubleClicked;
}
public DataState getButton2Down() {
	return button2Down;
}
public DataState getButton2Pressed() {
	return button2Pressed;
}
public DataState getButton2Released() {
	return button2Released;
}
public DataState getButtonDoubleClicked() {
	return buttonDoubleClicked;
}
public DataState getButtonDown() {
	return buttonDown;
}
public DataState getButtonPressed() {
	return buttonPressed;
}
public DataState getButtonReleased() {
	return buttonReleased;
}
public DataMouse getClone() {

	DataMouse newMouse = new DataMouse();

	newMouse.buttonDoubleClicked = buttonDoubleClicked.getClone();
	newMouse.buttonPressed = buttonPressed.getClone();
	newMouse.buttonReleased = buttonReleased.getClone();
	newMouse.buttonDown = buttonDown.getClone();

	newMouse.button1DoubleClicked = button1DoubleClicked.getClone();
	newMouse.button1Pressed = button1Pressed.getClone();
	newMouse.button1Released = button1Released.getClone();
	newMouse.button1Down = button1Down.getClone();

	newMouse.button2DoubleClicked = button2DoubleClicked.getClone();
	newMouse.button2Pressed = button2Pressed.getClone();
	newMouse.button2Released = button2Released.getClone();
	newMouse.button2Down = button2Down.getClone();

	newMouse.lastPosition = lastPosition.getClone();
	newMouse.lastPositionView = lastPositionView.getClone();
	newMouse.position = position.getClone();
	newMouse.positionView = positionView.getClone();
	newMouse.pressPositionView = pressPositionView.getClone();

	newMouse.velocity = velocity.getClone();
	newMouse.velocityView = velocityView.getClone();

	newMouse.sticky = sticky.getClone();

	if(_over!=null)
	{
		System.out.println("Transfer "+_over+" to "+newMouse.getRef());
		newMouse._over = _over ;
	}
	newMouse.setHeld( _lastHeld );
	newMouse.setHeld( _held );

	return newMouse;
}
public DataMouse getClone(String path) {

	DataMouse newMouse = new DataMouse();

	GrfxMLStoreProcessor.setCloneName( path,this,newMouse );

	newMouse.buttonDoubleClicked = buttonDoubleClicked.getClone(path);
	newMouse.buttonPressed = buttonPressed.getClone(path);
	newMouse.buttonReleased = buttonReleased.getClone(path);
	newMouse.buttonDown = buttonDown.getClone(path);

	newMouse.button1DoubleClicked = button1DoubleClicked.getClone(path);
	newMouse.button1Pressed = button1Pressed.getClone(path);
	newMouse.button1Released = button1Released.getClone(path);
	newMouse.button1Down = button1Down.getClone(path);

	newMouse.button2DoubleClicked = button2DoubleClicked.getClone(path);
	newMouse.button2Pressed = button2Pressed.getClone(path);
	newMouse.button2Released = button2Released.getClone(path);
	newMouse.button2Down = button2Down.getClone(path);

	newMouse.lastPositionView = lastPositionView.getClone(path);
	newMouse.positionView = positionView.getClone(path);
	newMouse.pressPositionView = pressPositionView.getClone(path);

	newMouse.velocityView = velocityView.getClone(path);

	newMouse.sticky = sticky.getClone(path);

	if(_over!=null)
	{
		newMouse._over=_over;
	}
	newMouse.setHeld( _lastHeld );
	newMouse.setHeld( _held );

	return newMouse;
}
public ITag getHeld() {
	return _held;
}
public ITag getLastHeld() {
	return _lastHeld;
}
public DataPoint getLastPosition() {
	return lastPosition;
}
public ITag getOver() {
	return _over;
}
public DataPoint getPosition() {
	return positionView;
}
public DataPoint getPressPosition() {
	return pressPosition;
}
public DataState getSticky() {
	return sticky;
}
public DataPoint getVelocity() {
	return velocity;
}
public void register(DataLinker store) {

	try{
		store.add(buttonPressed,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(buttonDoubleClicked,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(buttonReleased,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(buttonDown,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(lastPosition,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(position,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(pressPosition,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(velocity,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(sticky,this);
	}
	catch(LockException le)
	{}//Dummy catch

//--------
	try{
		store.add(button1Pressed,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button1DoubleClicked,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button1Released,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button1Down,this);
	}
	catch(LockException le)
	{}//Dummy catch
//---------
	try{
		store.add(button2Pressed,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button2DoubleClicked,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button2Released,this);
	}
	catch(LockException le)
	{}//Dummy catch

	try{
		store.add(button2Down,this);
	}
	catch(LockException le)
	{}//Dummy catch
}
public void replace(Field oldObj, Field newObj) {
	replace(oldObj, newObj, false);
}
public void replace(Field oldObj, Field newObj,boolean recursive) {

	if(buttonPressed==oldObj)
		buttonPressed=(DataState)newObj;

	if(buttonDoubleClicked==oldObj)
		buttonDoubleClicked=(DataState)newObj;

	if(buttonReleased==oldObj)
		buttonReleased=(DataState)newObj;

	if(buttonDown==oldObj)
		buttonDown=(DataState)newObj;

	if(lastPosition==oldObj)
		lastPosition=(DataPoint)newObj;

	if(position==oldObj)
		position=(DataPoint)newObj;

	if(pressPosition==oldObj)
		pressPosition=(DataPoint)newObj;

	if(velocity==oldObj)
		velocity=(DataPoint)newObj;

	if(sticky==oldObj)
		sticky=(DataState)newObj;

//----------
	if(button1Pressed==oldObj)
		button1Pressed=(DataState)newObj;

	if(button1DoubleClicked==oldObj)
		button1DoubleClicked=(DataState)newObj;

	if(button1Released==oldObj)
		button1Released=(DataState)newObj;

	if(button1Down==oldObj)
		button1Down=(DataState)newObj;

//----------
	if(button2Pressed==oldObj)
		button2Pressed=(DataState)newObj;

	if(button2DoubleClicked==oldObj)
		button2DoubleClicked=(DataState)newObj;

	if(button2Released==oldObj)
		button2Released=(DataState)newObj;

	if(button2Down==oldObj)
		button2Down=(DataState)newObj;
}
public void resetButtons() {

	try{
		buttonDoubleClicked.setValue( false,this );
		buttonPressed.setValue( false,this );
		buttonReleased.setValue( false,this );
		//buttonDown.setValue( false,this );

		button1Pressed.setValue( false,this );
		button1DoubleClicked.setValue( false,this );
		button1Released.setValue( false,this );
		//button1Down.setValue( false,this );

		button2Pressed.setValue( false,this );
		button2DoubleClicked.setValue( false,this );
		button2Released.setValue( false,this );
		//button2Down.setValue( false,this );

		//events = new Vector();
		//cutEvents = new Vector();
	}
	catch(LockException le){}//dummy catch
}
public void resetChanged() {

	buttonPressed.resetChanged();

	try{
		buttonDoubleClicked.setValue(false,this);
	}
	catch(LockException le){}//dummy catch
	buttonDoubleClicked.resetChanged();

	buttonReleased.resetChanged();

	buttonDown.resetChanged();

	lastPosition.resetChanged();
	lastPositionView.resetChanged();

	position.resetChanged();
	positionView.resetChanged();

	pressPosition.resetChanged();
	pressPositionView.resetChanged();

	velocity.resetChanged();
	velocityView.resetChanged();

	sticky.resetChanged();

//----------
	button1Pressed.resetChanged();

	try{
		button1DoubleClicked.setValue(false,this);
	}
	catch(LockException le){}//dummy catch
	button1DoubleClicked.resetChanged();

	button1Released.resetChanged();

	button1Down.resetChanged();

//----------
	button2Pressed.resetChanged();

	try{
		button2DoubleClicked.setValue(false,this);
	}
	catch(LockException le){}//dummy catch
	button2DoubleClicked.resetChanged();

	button2Released.resetChanged();

	button2Down.resetChanged();

}
public void setHeld(ITag newHeld) {
	if(_held!=null)
	{
		_lastHeld = _held;
	}

	_held = newHeld;
}

public void setOver(ITag newOver) {
	_over = newOver;
}

public String togrfxML(String name) {
	String xml = "<" + name;

	if(!NameHelper.isSystemName(getId()))
	{
		xml += " id=\""+getId()+"\"";
	}

	xml += ">";
	xml += buttonPressed.togrfxML(Token.BUTTON_PRESSED);
	xml += buttonDoubleClicked.togrfxML(Token.BUTTON_DOUBLE_CLICKED);
	xml += buttonReleased.togrfxML(Token.BUTTON_RELEASED);
	xml += buttonDown.togrfxML(Token.BUTTON_DOWN);
	xml += lastPosition.togrfxML(Token.LAST_POSITION);
	xml += position.togrfxML(Token.POSITION);
	xml += pressPosition.togrfxML(Token.PRESS_POSITION);
	xml += velocity.togrfxML(Token.VELOCITY);
	xml += sticky.togrfxML(Token.STICKY);

	xml += button1Pressed.togrfxML(Token.BUTTON1_PRESSED);
	xml += button1DoubleClicked.togrfxML(Token.BUTTON1_DOUBLE_CLICKED);
	xml += button1Released.togrfxML(Token.BUTTON1_RELEASED);
	xml += button1Down.togrfxML(Token.BUTTON1_DOWN);

	xml += button2Pressed.togrfxML(Token.BUTTON2_PRESSED);
	xml += button2DoubleClicked.togrfxML(Token.BUTTON2_DOUBLE_CLICKED);
	xml += button2Released.togrfxML(Token.BUTTON2_RELEASED);
	xml += button2Down.togrfxML(Token.BUTTON2_DOWN);

	xml += "</" + name + ">\n";
	return xml;
}
public String togrfxML(String name,TagModifier modifier) {
	return togrfxML(name);
}
public String toString()
{
	if(GrfxMLEngine.DEBUG)
		return(togrfxML( DEFAULT_ID.substring(1) ));

	String xml = "<"+DEFAULT_ID.substring(1)+"/>";

	return xml;
}
public void translate(DataTranslation t) {
	try {
		GrfxMLProcessor.reverseTranslate(lastPositionView,TagModifier.POINT_TYPE_POINT, t, lastPosition);
	} catch (LockException le) {
		le.printStackTrace();
	}
	try {
		GrfxMLProcessor.reverseTranslate(positionView,TagModifier.POINT_TYPE_POINT, t, position);
	} catch (LockException le) {
		le.printStackTrace();
	}
	try {
		GrfxMLProcessor.reverseTranslate(pressPositionView,TagModifier.POINT_TYPE_POINT, t, pressPosition);
	} catch (LockException le) {
		le.printStackTrace();
	}
	try {
		GrfxMLProcessor.reverseTranslate(velocityView,TagModifier.POINT_TYPE_VECTOR, t, velocity);
	} catch (LockException le) {
		le.printStackTrace();
	}
}


	public void resetEvents()
	{
		events = new Vector();
	}

	public void addEvent(MouseEvent event)
	{
		if(events==null)
		{
			events=new Vector();
		}
		events.addElement(event);
	}

	public int getCutEventsSize() {
		if(cutEvents==null)
		{
			return 0;
		}
		return cutEvents.size();
	}

	public MouseEvent getCutEvent(int index) {
		return (MouseEvent)cutEvents.elementAt(index);
	}

	public void cutEvents() {
		cutEvents = events;
		events = new Vector();
	}
	/**
	 * @param events The events to set.
	 */
	public void setEvents(Vector events) {
		this.events = events;
	}
}
